package zhoug.common.camera.ui.ocr;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.ImageFormat;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.hardware.Camera;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import zhoug.common.R;
import zhoug.common.camera.core.CameraSP;
import zhoug.common.camera.core.camera.CameraEventCallback;
import zhoug.common.camera.core.camera.CameraManager;
import zhoug.common.camera.core.camera.CameraSurfaceView;
import zhoug.common.camera.ui.ocr.overlay.IdCardZOverlayView;
import zhoug.common.utils.AppUtils;
import zhoug.common.utils.BitmapUtils;
import zhoug.common.view.ZOverlayView;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;

import static zhoug.common.camera.core.camera.CameraManager.getCacheImagePath;

/**
 * 拍照
 */
public class CameraOcrImageActivity extends AppCompatActivity implements View.OnClickListener {
    private static final String TAG = "CameraOcrImageActivity";
    private CameraSurfaceView surfaceView;
    private ImageView ivFlush;
    private ImageView ivChangeCamera;
    private ImageView ivCancel;
    private ImageView ivOk;
    private ImageView ivImage;

    private TextView tvHint;
    private TextView tvCapture;
    private TextView tvFlash;
    private ViewGroup btnFlush;
    private ViewGroup uiCapture;
    private ViewGroup uiCaptureFinish;

    private CameraManager mCameraManager;


    private int picWidth;
    private int picHeight;


    private String keepPath = null;
    private String mFlashMode;
    private int mCameraFacing = Camera.CameraInfo.CAMERA_FACING_BACK;

    private List<String> flashList = new ArrayList<>();

    private volatile boolean initFlashList = false;
    private int flashIndex = -1;

    private IdCardZOverlayView idCardOverlayView;
    private ZOverlayView ZOverlayView;

    //ocr图片类型
    /**
     * {@link OcrType}
     */
    private int type = 0;
    private float ratio=0.7f;
    private boolean scaleEnabled=true;
    private boolean translateEnabled=true;
    private int sure= ZOverlayView.SURE_WIDTH;
    private float sureWeight=0.7f;
    private String mHint;//提示文字
    private int mHintTextColor;//提示文字颜色


    public static final String EXTRA_PATH = "path";
    public static final String EXTRA_TYPE = "type";
    public static final String EXTRA_SURE = "sure";
    public static final String EXTRA_SURE_WEIGHT = "sureWeight";
    public static final String EXTRA_RATIO = "ratio";
    public static final String EXTRA_SCALE_ENABLED = "scaleEnabled";
    public static final String EXTRA_TRANSLATE_ENABLED = "translateEnabled";
    public static final String EXTRA_HINT = "hint";
    public static final String EXTRA_HINT_TEXT_COLOR = "hintTextColor";




    /**
     * @param activity
     * @param requestCode
     * @param type
     * @param keepPath
     */
    public static void startForResult(@NonNull Activity activity, int requestCode, int type, String keepPath) {
        Intent intent = new Intent(activity, CameraOcrImageActivity.class);
        intent.putExtra(EXTRA_PATH, keepPath);
        intent.putExtra(EXTRA_TYPE, type);
        activity.startActivityForResult(intent, requestCode);
    }

    /**
     * @param fragment
     * @param context
     * @param requestCode
     * @param type
     * @param keepPath
     */
    public static void startForResult(@NonNull Fragment fragment, @NonNull Context context, int requestCode, int type, String keepPath) {
        Intent intent = new Intent(context, CameraOcrImageActivity.class);
        intent.putExtra(EXTRA_PATH, keepPath);
        intent.putExtra(EXTRA_TYPE, type);
        fragment.startActivityForResult(intent, requestCode);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.common_camera_activity_camera_orc_image);
        initData();
        findViews();
        initCamera();
        if(mHint!=null){
            tvHint.setText(mHint);
            tvHint.setTextColor(mHintTextColor);
            tvHint.setVisibility(View.VISIBLE);
        }else{
            tvHint.setVisibility(View.GONE);
        }
    }

    /**
     * 获取intent中的数据
     */
    private void initData() {
        Intent intent = getIntent();
        if (intent != null) {
            keepPath = intent.getStringExtra(EXTRA_PATH);
            type = intent.getIntExtra(EXTRA_TYPE, 0);
            ratio = intent.getFloatExtra(EXTRA_RATIO, 0.7f);
            if(ratio<=0){
                ratio=0.7f;
            }
            scaleEnabled = intent.getBooleanExtra(EXTRA_SCALE_ENABLED, true);
            translateEnabled = intent.getBooleanExtra(EXTRA_TRANSLATE_ENABLED, true);
            sure = intent.getIntExtra(EXTRA_SURE, ZOverlayView.SURE_WIDTH);
            sureWeight = intent.getFloatExtra(EXTRA_SURE_WEIGHT,0.7f);
            if(sureWeight<=0 || sureWeight>=1){
                sureWeight=0.7f;
            }
            mHint=intent.getStringExtra(EXTRA_HINT);
            mHintTextColor=intent.getIntExtra(EXTRA_HINT_TEXT_COLOR, Color.parseColor("#aa00ff00"));
        }

        Point screenSize = AppUtils.getScreenSize();
        picWidth = screenSize.x;
        picHeight = screenSize.y;
        mFlashMode = CameraSP.getFlashMode(this);
    }

    private void findViews() {
        surfaceView = findViewById(R.id.surfaceView);
        ivFlush = findViewById(R.id.iv_flush);
        ivChangeCamera = findViewById(R.id.iv_change_camera);
        ivCancel = findViewById(R.id.iv_cancel);
        ivOk = findViewById(R.id.iv_ok);
        tvCapture = findViewById(R.id.tv_capture);
        btnFlush = findViewById(R.id.btn_flush);
        uiCapture = findViewById(R.id.ui_capture);
        uiCaptureFinish = findViewById(R.id.ui_capture_finish);
        ivImage = findViewById(R.id.iv_image);
        tvFlash = findViewById(R.id.tv_flush);
        idCardOverlayView = findViewById(R.id.idCardOverlayView);
        ZOverlayView = findViewById(R.id.overlayView);
        tvHint = findViewById(R.id.tv_hint);

        if (type == OcrType.IDCARD_FRONT) {
            idCardOverlayView.setVisibility(View.VISIBLE);
            ZOverlayView.setVisibility(View.GONE);
            idCardOverlayView.setFace(IdCardZOverlayView.FACE_FRONT);
        } else if (type == OcrType.IDCARD_BACK) {
            idCardOverlayView.setVisibility(View.VISIBLE);
            ZOverlayView.setVisibility(View.GONE);
            idCardOverlayView.setFace(IdCardZOverlayView.FACE_BACK);
        } else {
            idCardOverlayView.setVisibility(View.GONE);
            ZOverlayView.setVisibility(View.VISIBLE);
            ZOverlayView.setRatio(ratio);
            ZOverlayView.setScaleEnabled(scaleEnabled);
            ZOverlayView.setTranslateEnabled(translateEnabled);
            ZOverlayView.setSure(sure);
            ZOverlayView.setSureWeight(sureWeight);
        }

        addListener();
    }

    private void addListener() {
        btnFlush.setOnClickListener(this);
        ivChangeCamera.setOnClickListener(this);
        ivCancel.setOnClickListener(this);
        ivOk.setOnClickListener(this);
        tvCapture.setOnClickListener(this);
        ivImage.setOnClickListener(null);
    }

    /**
     * 初始化相机
     */
    private void initCamera() {
        if (mCameraManager == null) {
            mCameraManager = new CameraManager();
            surfaceView.setCameraManager(mCameraManager);
            mCameraManager.setCameraFacing(mCameraFacing)
                    .setSurfaceView(surfaceView)
                    .setContinuePreView(false)
                    .setPicSize(picWidth, picHeight)
                    .setPreviewFormat(ImageFormat.NV21)
                    .setPreSize(picWidth, picHeight);
            mCameraManager.setCameraFacing(mCameraFacing);
            //预览回掉
            mCameraManager.setPreviewCallback((data, camera) -> {
                //初始化闪光灯模式集合
                if (!initFlashList) {
                    Log.d(TAG, "onPreviewFrame:初始化闪光灯模式集合");
                    initFlashList = true;
                    flashList.clear();
                    Camera.Parameters parameters = camera.getParameters();
                    List<String> supportedFlashModes = parameters.getSupportedFlashModes();
                    if (supportedFlashModes == null) {
                        return;
                    }
                    if (supportedFlashModes.contains(Camera.Parameters.FLASH_MODE_AUTO)) {
                        flashList.add(Camera.Parameters.FLASH_MODE_AUTO);
                        Log.d(TAG, "onPreviewFrame:flash支持自动");
                    }
                    if (supportedFlashModes.contains(Camera.Parameters.FLASH_MODE_ON)) {
                        flashList.add(Camera.Parameters.FLASH_MODE_ON);
                        Log.d(TAG, "onPreviewFrame:flash支持开启");
                    }
                    if (supportedFlashModes.contains(Camera.Parameters.FLASH_MODE_OFF)) {
                        flashList.add(Camera.Parameters.FLASH_MODE_OFF);
                        Log.d(TAG, "onPreviewFrame:flash支持关闭");
                    }
                    if (supportedFlashModes.contains(Camera.Parameters.FLASH_MODE_TORCH)) {
                        flashList.add(Camera.Parameters.FLASH_MODE_TORCH);
                        Log.d(TAG, "onPreviewFrame:flash支持手电筒");
                    }
                    //设置模式
                    if (mFlashMode != null && flashList.size() > 0) {
                        //-1不支持
                        flashIndex = flashList.indexOf(mFlashMode);
                        if (flashIndex < 0) {
                            flashIndex = 0;
                        }
                        setFlashMode(flashIndex);
                    }
                }

                capture(data, camera);


            });
        }
        mCameraManager.setCameraEventCallback(new CameraEventCallback() {
            @Override
            public void onOpenCameraError(int errorCode, String msg) {
                Toast.makeText(CameraOcrImageActivity.this, msg, Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onOpenCameraSuccess(android.graphics.Camera camera) {

            }
        });
        mCameraManager.init();

    }

    /**
     * 捕获预览图片为bitmap
     *
     * @param data
     * @param camera
     */
    private void capture(byte[] data, Camera camera) {
        if (capturing) {
            Bitmap bitmap = BitmapUtils.previewDataToBitmap(data, camera, mCameraManager.getPreRotation());
            if (bitmap != null) {
                Log.d(TAG, "onPreviewFrame:bitmap=" + bitmap.getWidth() + "," + bitmap.getHeight());
                int visibility = idCardOverlayView.getVisibility();
                int visibility1 = ZOverlayView.getVisibility();
                if (visibility == View.VISIBLE) {
                    bitmap = cutBitmap(idCardOverlayView.getRectRatio(), bitmap);
                } else if (visibility1 == View.VISIBLE) {
                    bitmap = cutBitmap(ZOverlayView.getRectRatio(), bitmap);
                }

                Log.d(TAG, "onPreviewFrame:bitmap=" + bitmap.getWidth() + "," + bitmap.getHeight());
                if (keepPath == null) {
                    keepPath = getCacheImagePath(CameraOcrImageActivity.this);
                }
                boolean b = BitmapUtils.keepBitmap(bitmap, 100, keepPath);
                if (b) {
                    toast("成功");
                    if (ivImage != null) {
                        ivImage.setImageBitmap(bitmap);
                    }
                    setUiAfterCapture(true);
                } else {
                    toast("失败");
                }
            } else {
                toast("失败");
            }
            capturing = false;
        }
    }
    /**
     * 根据rectRatio比例裁剪图片
     *
     * @param rectRatio 比例
     * @param bitmap
     * @return
     */
    public  static Bitmap cutBitmap(RectF rectRatio, Bitmap bitmap) {
        int w = bitmap.getWidth();
        int h = bitmap.getHeight();
        Rect rect = new Rect((int) (w * rectRatio.left), (int) (h * rectRatio.top), (int) (w * rectRatio.right), (int) (h * rectRatio.bottom));
        Log.d(TAG, "cutBitmap:rectRatio=" + rectRatio);
        Log.d(TAG, "width:" + w + ",height=" + h);
        Log.d(TAG, "cutBitmap:rect=" + rect);
        int x = rect.left;
        int y = rect.top;
        int width = rect.right - rect.left;
        int height = rect.bottom - rect.top;
        return Bitmap.createBitmap(bitmap, x, y, width, height);
    }
    /**
     * 设置闪光灯模式
     */
    private void setFlashMode(int index) {
        if (flashList != null && flashList.size() > 0) {
            flashIndex = index;
            if (flashIndex >= flashList.size() || flashIndex < 0) {
                flashIndex = 0;
            }
            mFlashMode = flashList.get(flashIndex);
            mCameraManager.setFlashMode(mFlashMode);
            setTvFlash();
            CameraSP.keepFlashMode(this, mFlashMode);
            Log.d(TAG, "setFlashMode:" + mFlashMode);
        } else {
            toast("没有支持的模式");
        }
    }

    private void setTvFlash() {
        if (Camera.Parameters.FLASH_MODE_AUTO.equals(mFlashMode)) {
            tvFlash.setText("自动");
        } else if (Camera.Parameters.FLASH_MODE_ON.equals(mFlashMode)) {
            tvFlash.setText("打开");
        } else if (Camera.Parameters.FLASH_MODE_OFF.equals(mFlashMode)) {
            tvFlash.setText("关闭");
        } else if (Camera.Parameters.FLASH_MODE_TORCH.equals(mFlashMode)) {
            tvFlash.setText("常亮");
        }
    }

    /**
     * 拍照过后改变显示的ui
     *
     * @param captureFinish
     */
    private void setUiAfterCapture(boolean captureFinish) {
        if (captureFinish) {
            if (uiCapture != null) {
                uiCapture.setVisibility(View.GONE);
            }
            if (uiCaptureFinish != null) {
                uiCaptureFinish.setVisibility(View.VISIBLE);
            }
        } else {
            if (uiCapture != null) {
                uiCapture.setVisibility(View.VISIBLE);
            }
            if (uiCaptureFinish != null) {
                uiCaptureFinish.setVisibility(View.GONE);
            }
        }
    }


    /**
     * 完成拍照,
     */
    private void captureResult() {
        File file = new File(keepPath);
        if(file.exists()){
            AppUtils.scannerFile(this,keepPath);
        }
        Intent intent = new Intent();
        intent.putExtra(EXTRA_PATH, keepPath);
        intent.putExtra(EXTRA_TYPE, type);
        intent.setData(Uri.fromFile(file));
        setResult(RESULT_OK, intent);
        finish();
    }

    private volatile boolean capturing = false;

    @Override
    public void onClick(View v) {
        int id = v.getId();
        if (id == R.id.btn_flush) {
            setFlashMode(++flashIndex);

        } else if (id == R.id.iv_change_camera) {
            //切换摄像头
            if (mCameraManager != null) {
                mCameraManager.changeCamera();
                flashList.clear();
                initFlashList = false;
                mCameraFacing = mCameraManager.getCameraFacing();
                CameraSP.keepCameraFacing(this, mCameraFacing);
            }


        } else if (id == R.id.tv_capture) {
            //拍照
            capturing = true;
        } else if (id == R.id.iv_cancel) {
            //取消上次的拍摄,清除图片
            if (keepPath != null) {
                File file = new File(keepPath);
                if (file.exists()) {
                    boolean delete = file.delete();
                }
            }
            //开始预览
            if (mCameraManager != null) {
                mCameraManager.startPreview();
                setUiAfterCapture(false);
            }
        } else if (id == R.id.iv_ok) {
            captureResult();
        }
    }

    @Override
    public void onBackPressed() {
        if (uiCaptureFinish != null && uiCaptureFinish.getVisibility() == View.VISIBLE) {
            mCameraManager.startPreview();
            setUiAfterCapture(false);
            return;
        }
        setResult(RESULT_CANCELED);
        super.onBackPressed();
    }

    private void toast(String msg) {
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
    }


    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, "onResume:");
    }

    @Override
    protected void onPause() {
        super.onPause();
        Log.d(TAG, "onPause:");
    }
}
